import { RenderTask, type PixelPoint } from "./commonTypes"
import { renderPixelCamera } from "./renderers/cameraRender"
import { renderPixelScene } from "./renderers/sceneRender"
import { renderPixelSimple } from "./renderers/simpleRender"
import { renderPixelSphereOne, renderPixelSphereMore } from "./renderers/sphereRender"
import { renderPixelReflect, renderPixelReflectAttenuation } from "./renderers/reflectRender"
import { renderPixelMaterial, renderPixelMaterialFuzz } from "./renderers/materialRender"

onmessage = (e) => {
  const { data } = e
  if (data.type === 'render') {
    const tmpTask = data.task
    const renderType = data.renderType
    render(tmpTask, renderType)
  }
}


/**
   * 渲染像素
   * @param task 
   */
function render(task: RenderTask, renderType: string) {
  const { pixels, width, height } = task
  // 部分像素渲染长度
  const len = 400
  // 部分的任务数据
  let resultTask = new RenderTask([], width, height)

  // 渲染每个像素
  for (let px of pixels) {
    renderPixel(px, width, height, renderType)
    resultTask.pixels.push(px)

    if (resultTask.pixels.length >= len) {
      self.postMessage({
        type: 'partComplete',
        task: resultTask,
      })

      resultTask = new RenderTask([], width, height)
    }
  }

  // 返回渲染完成的消息
  self.postMessage({
    type: 'allComplete',
    task: resultTask
  })
}

function renderPixel(px: PixelPoint, width: number, height: number, renderType: string) {
  switch (renderType) {
    case 'simple':
      renderPixelSimple(px, width, height)
      break;
    case 'scene':
      renderPixelScene(px, width, height)
      break;
    case 'camera':
      renderPixelCamera(px, width, height)
      break;
    case 'sphereOne':
      renderPixelSphereOne(px, width, height)
      break;
    case 'sphereMore':
      renderPixelSphereMore(px, width, height)
      break;
    case 'reflect':
      renderPixelReflect(px, width, height)
      break;
    case 'reflectAttenuation':
      renderPixelReflectAttenuation(px, width, height)
      break;
    case 'material':
      renderPixelMaterial(px, width, height)
      break;
    case 'materialFuzz':
      renderPixelMaterialFuzz(px, width, height)
      break;
  }
}

/**
 * worker已经建立
 */
self.postMessage({
  type: 'init'
})